<?php


namespace app\controller;


use app\job\Capture;
use app\job\MotoCapture;
use app\model\Faces;
use app\model\ViidDeviceRelate;
use app\model\ViidToken;
use app\model\ViidUsers;
use fast\Http;
use think\cache\driver\Redis;
use think\facade\Cache;
use think\facade\Log;
use think\facade\Queue;
use think\facade\Request;

class ViidDevice extends BackendController{
    protected $model = null;
    var $Register_url="/VIID/System/Keepalive";
    public function _initialize()
    {
        //parent::_initialize();
        $this->model = new \app\model\ViidDevice();
    }

    public function sta(){
        $data['count']=$this->model->count();
        $data['online_count']=$this->model->where('is_online',1)->count();
        $data['offline_count']=$data['count']-$data['online_count'];
        $data['online_percent']=round($data['online_count']/$data['count']*100,2);
        $this->success('获取成功',$data);
    }

    public function ana_where($where){
        foreach ($where as &$item){
            if($item[0]=='name'){
                //$item=[['name',$item[1],'%'.$item[2].'%'],['name_code',$item[1],'%'.$item[2].'%'],'OR'];
                //$where[]=['name_code','LIKE','%'.$item[2].'%'];
                //$where['_logic']='or';
                $item=['name|device_id',$item[1],'%'.$item[2].'%'];
            }elseif ($item[0]=='label_ids'){
                $item=['label_ids','find in set',$item[2]];
            }elseif ($item[0]=='type_id'){
                $vids=ViidDeviceRelate::where('type_id',$item[2])->column('device_id');
                if($vids){
                    $item=['id','in',$vids];
                }else{
                    $item=['id','=',-27];
                }
            }
        }
        return $where;
    }
    public function after_add($params)   {
        $aizone=\app\model\Aizone::where('id',$params['aizone_id'])->find();
        if($aizone){
            \app\model\ViidDevice::where('id',$params['id'])->save(['aizone_name'=>$aizone['name']]);
        }
        if($params['label_ids']){
            $this->model->calLabels($params['label_ids']);
        }
        //如果是门禁卡
        if($params['dev_type']==1){
            $_panel=new \app\model\Panel();
            $where[]=['op_rights','<>',''];
            $where[]=['panel_type','=',$params['panel_type']];
            $old=$this->model->where($where)->find();
            if($old){
                \app\model\ViidDevice::where('id',$params['id'])->save(['op_rights'=>$old['op_rights']]);
                $_panel->bind_group($old['op_rights'],$params['ape_id'],$params['panel_type']);
            }else{
                $_panel->add_group($params['id'],$params['panel_type'],$aizone['name'],$params['ape_id'],$aizone['third_code']);
            }

        }
    }

    public function after_edit($params,$old)   {
        $aizone=\app\model\Aizone::where('id',$params['aizone_id'])->find();
        if($aizone){
            \app\model\ViidDevice::where('id',$params['id'])->save(['aizone_name'=>$aizone['name']]);
        }
        if($params['label_ids']){
            $this->model->calLabels($params['label_ids']);
        }
        if($old['label_ids']){
            $this->model->calLabels($old['label_ids']);
        }
    }

    /**
     * 1400收图接口
     * @return mixed
     */
    public function face(){
        //Faces::create(['content'=>file_get_contents('php://input'),'header'=>json_encode(Request::header())]);
        $content=file_get_contents('php://input');
        //$content=json_decode($content);
        //Cache::tag('jygd'.rand(1,4))->set(md5(time()),$content,3600);
        $User_Identify=Request::header("User-Identify");
        //Log::info("1400收图：".$User_Identify);
        $check=$this->check_token($User_Identify);
        if(!$check)
        {
            //dump('Faces 授权无效或已过期');
            $msg=array(
                'ResponseStatusObject'=>array(
                    //'Id'=>$User_Identify,
                    'LocalTime'=>time(),
                    'RequestURL'=>$this->Register_url,
                    'StatusCode'=>7,
                    'StatusString'=>'未授权的：请求需要用户认证后才能访问该资源。如果请求包含无效认证数据，则发送该响应消息。'
                )
            );

            //Log::error('Faces 授权无效或已过期'.$User_Identify);

            return $this->res1400(1,$msg);
        }else{
            $job_data = [];
            $job_data["ts"] = time();
            $job_data["bizid"] = uniqid();
            $job_data["params"] =$content;
            $is_pushed=Queue::push(Capture::class,$job_data,'capture_list');
            //Log::info("推送：".$content);
            $msg_info = array(
                'ResponseStatusListObject'=>array(
                    'ResponseStatusObject'=>[]
                ),
                'StatusCode'=>0,
                'StatusString'=>'全部操作成功'
            );
            return $this->res1400(200,$msg_info);
        }

    }

    /**
     * 1400收机动车图接口
     * @return mixed
     */
    public function motor_vehicle(){
        //Faces::create(['content'=>file_get_contents('php://input'),'header'=>json_encode(Request::header())]);
        $content=file_get_contents('php://input');
        Log::info("1400机动车收图：".$content);
        //$content=json_decode($content);
        //Cache::tag('jygd'.rand(1,4))->set(md5(time()),$content,3600);
        $User_Identify=Request::header("User-Identify");
        $check=$this->check_token($User_Identify);
        if(!$check)
        {
            //dump('Faces 授权无效或已过期');
            $msg=array(
                'ResponseStatusObject'=>array(
                    //'Id'=>$User_Identify,
                    'LocalTime'=>time(),
                    'RequestURL'=>$this->Register_url,
                    'StatusCode'=>7,
                    'StatusString'=>'未授权的：请求需要用户认证后才能访问该资源。如果请求包含无效认证数据，则发送该响应消息。'
                )
            );

            //Log::error('Faces 授权无效或已过期'.$User_Identify);

            return $this->res1400(1,$msg);
        }else{
            $job_data = [];
            $job_data["ts"] = time();
            $job_data["bizid"] = uniqid();
            $job_data["params"] =$content;
            $is_pushed=Queue::push(MotoCapture::class,$job_data,'car_capture_list');
            //Log::info("推送：".$content);
            $msg_info = array(
                'ResponseStatusListObject'=>array(
                    'ResponseStatusObject'=>[]
                ),
                'StatusCode'=>0,
                'StatusString'=>'全部操作成功'
            );
            return $this->res1400(200,$msg_info);
        }

    }

    public function keep_live(){
        //Faces::create(['content'=>file_get_contents('php://input'),'header'=>json_encode(apache_request_headers()),'user_id'=>Request::header('User-Identify')]);
        $input=file_get_contents('php://input');
        //Log::info("1400保活：".json_encode(['content'=>$input,'header'=>json_encode(apache_request_headers()),'user_id'=>Request::header('User-Identify')]));
        $User_Identify=Request::header("User-Identify");
        if(!$User_Identify){
            $input=json_decode($input,true);
            $User_Identify=$input['KeepaliveObject']['DeviceID'];
        }
        $check=$this->check_token($User_Identify);
        //Log::info('check:'.$check);
        //Log::info('User_Identify:'.$User_Identify);
        if($check){
            $where['device_id']=$User_Identify;
            $viid=\app\model\ViidDevice::where($where)->find();
            $viid->is_online=1;
            $viid->save();
            if($viid->is_nvr==1){
                $list_where=['device_id','like',substr($User_Identify,0,17).'%'];
                Log::info('nvr::'.substr($User_Identify,0,17));
                $subs=ViidDevice::where($list_where)->select();
                foreach ($subs as $sub) {
                    $sub->is_online=1;
                    $sub->save();
                    $this->set_token($sub->device_id);
                }
            }

            $system_time=date("YmdHis");
            $msg=array(
                'ResponseStatusObject'=>array(
                    'Id'=>$User_Identify,
                    'LocalTime'=>$system_time,
                    'RequestURL'=>$this->Register_url,
                    'StatusCode'=>0,
                    'StatusString'=>'成功：请求已经成功'
                )
            );
            return $this->res1400(200,$msg);
        }else{
            $msg=array(
                'ResponseStatusObject'=>array(
                    //'Id'=>$User_Identify,
                    'LocalTime'=>time(),
                    'RequestURL'=>$this->Register_url,
                    'StatusCode'=>7,
                    'StatusString'=>'未授权的：请求需要用户认证后才能访问该资源。如果请求包含无效认证数据，则发送该响应消息。'
                )
            );

            //Log::error('Faces 授权无效或已过期'.$User_Identify);

            return $this->res1400(1,$msg);
        }


    }

    public function register(Request $request) {
        //Faces::create(['content'=>file_get_contents('php://input'),'header'=>json_encode(apache_request_headers())]);
        Log::info("1400注册：".json_encode(['content'=>file_get_contents('php://input'),'header'=>json_encode(apache_request_headers()),'auth'=>Request::header('Authorization')]));
        $info= request()->getContent();
        $info=json_decode($info);

        if(!$info) return $this->error('Parameter error');
        $ip = request()->ip();
        $Authorization= request()->header('Authorization');
        $Register_url="/VIID/System/Register";
        $mode=0;
        if(!isset($info->RegisterObject->DeviceID)) return $this->error('DeviceID Not Required','400');

        $DeviceID=$info->RegisterObject->DeviceID;
        $system_time=date("YmdHis");
        if(empty($Authorization)) $mode=1;


        //if(!isset($info->RegisterObject->DeviceID)) $mode=0; //第一次注册

        $realm='admin';
        if($mode==1)
        {
            $a=time();
            $b=md5($a);
            $c=$a.':'.$b;
            $token=base64_encode($c);
            //Log::info("第一次:".$token);

            $sql=array(
                'ip'=>$ip,
                'token'=>$token
            );

            //VIIDTokenModel::insert($sql);

            if(!Cache::has('viid_token::'.$ip))
            {
                ViidToken::create($sql);
            }
            else
            {
                ViidToken::where('ip',$ip)->update(['token'=>$token]);
            }

            Cache::set('viid_token::'.$ip,$token);
            /*header_remove('Content-Type');
            header("content-type: application/VIID+JSON");
            header('HTTP/1.1 401 Unauthorized');
            header('WWW-Authenticate: Digest realm="Top Secret",nonce="9d9310dff470d3ae4a1b875da17b205f"');
            die();*/

            return $this->res1400('401',"",['Content-Type'=>'application/VIID+JSON',
                'WWW-Authenticate'=>'Digest realm="'.$realm.'",qop="auth",nonce="'.$token.'"','User-Agent'=>'LiveVIS',
                'Access-Control-Allow-Credentials'=>true,
                'Access-Control-Allow-Origin'=>'http://192.168.1.39:8081','Vary'=>'Origin','Connection'=>'close']);

        }

        if($mode==0)
        {
            //Log::info("第二次:");

            $db=$this->model->where('device_id',$DeviceID)->find();


            if(!$db)
            {
                Log::info("未找到设备:".$DeviceID);
                $msg=[
                    'ResponseStatusObject'=>[
                        'Id'=>$DeviceID,
                        'LocalTime'=>$system_time,
                        'RequestURL'=>$Register_url,
                        'StatusCode'=>4,
                        'StatusString'=>'系统不存在'
                    ]
                ];

                return $this->res1400(1,$msg);
            }


            $user=$db->user_id;
            $password=$db->password;
            $auth='auth';


            $first_time=strstr($Authorization,'cnonce');
            $second_time=strstr($first_time,'="');
            $third_time=substr($second_time,2,50);
            $search_time=strpos($third_time,'"');
            $cnonce=substr($second_time,2,$search_time);

            //var_dump($cnonce);


            $ha1="$user:$realm:$password";
            //Log::info("ha1:".$ha1);
            $ha1=md5(utf8_encode($ha1));

            $nonce=Cache::get('viid_token::'.$ip);
            //Log::info("nonce:".$nonce);

            $nc_first=strstr($Authorization,'nc=');
            $noncecount = substr($nc_first,3,8);
            //var_dump($nonce);

            $HA2 = "POST:$Register_url";
            //Log::info("HA2:::".$HA2);
            $HA2 = md5(utf8_encode($HA2));
            $response= "$ha1:$nonce:$noncecount:$cnonce:$auth:$HA2";
            //Log::info("response:::".$response);
            //var_dump($cnonce,$auth);
            $utf8_response=utf8_encode($response);
            $response= md5($utf8_response);
            //$auth_give="Digest username=\"$user\", realm=\"$realm\", qop=\"$auth\", nonce=\"$nonce\", uri=\"$Register_url\", cnonce=\"$cnonce\", nc=$noncecount, response=\"$response\"";

            $get_response=strstr($Authorization,'response=');
            $res_response=substr($get_response,10,32);
            //Log::info('response:::'.$response);
            //Log::info('res_resp:::'.$res_response);
            if($response==$res_response)
            {
                $msg=[
                    'ResponseStatusObject'=>[
                        'Id'=>$DeviceID,
                        'LocalTime'=>$system_time,
                        'RequestURL'=>$Register_url,
                        'StatusCode'=>0,
                        'StatusString'=>'成功：请求已经成功'
                    ]
                ];

                $token_time=time()+600;

                //ViidUsers::where('device_id',$DeviceID)->update(['token_time'=>$token_time]);

                Cache::set('viid_token_device::'.$DeviceID,$token_time,600);
                //Cache::set('viid_token_device::'.$DeviceID,'auth',$response);
                return $this->res1400(200,$msg);
            }
            else
            {
                Log::info('注册失败:'.$DeviceID);
                $msg=[
                    'ResponseStatusObject'=>[
                        'Id'=>$DeviceID,
                        'LocalTime'=>$system_time,
                        'RequestURL'=>$Register_url,
                        'StatusCode'=>4,
                        'StatusString'=>'签名验证失败'
                    ]
                ];
                return $this->res1400( 1,$msg);
            }
        }
    }

    public function check_token($device_id) {
        if(Cache::get('viid_token_device::'.$device_id)){
            Cache::set('viid_token_device::'.$device_id,time(),600);
            return true;
        }else{
            return false;
        }
    }
    public function set_token($device_id){
        Cache::set('viid_token_device::'.$device_id,time(),600);
    }

    public function after_index($lists){
        foreach ($lists as &$list){
            if($list['is_online']==1&&!Cache::get('viid_token_device::'.$list['device_id'])){
                \app\model\ViidDevice::where('id',$list['id'])->save(['is_online'=>2]);
                $list['is_online']=2;
            }
        }
        return $lists;
    }

    /**
     * 删除分组设备
     * @param $device_id
     * @param $type_id
     * @return void
     */
    public function del_type($device_id,$type_id){
        ViidDeviceRelate::where(['device_id'=>$device_id,'type_id'=>$type_id])->delete();
        $this->success('删除成功');
    }
}